//
//  HsNotificationUtil.m
//  Pods
//
//  Created by txj on 2017/3/25.
//
//

#import "HsNotificationUtil.h"
#import <SVProgressHUD.h>
#import "NSDate+Extension.h"
#import "NSDictionary+Extra.h"
#import "NSString+Extra.h"
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif

#define ktimes @"times"
#define kcontent @"content"
@interface HsNotificationUtil()<UNUserNotificationCenterDelegate>

@property (nonatomic,strong) NSDictionary *dict;
@property (nonatomic,copy) NSString *notifyId;
@end

#define kNotificationCategoryIdentifile @"kNotificationCategoryIdentifile"
#define kLocalNotificationKey @"kLocalNotificationKey"
@implementation HsNotificationUtil

+ (instancetype)shareInstance {
    static HsNotificationUtil* _instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super alloc] init];
    });
    return _instance;
}

-(void)addNotification:(NSString *)notifyId userData:(NSDictionary *)userData {
    self.dict = userData;
    self.notifyId = notifyId;
    NSInteger times = [userData[ktimes] integerValue] / 1000;
    if (times <= 0) {
//        [SVProgressHUD showErrorWithStatus:@"时间已过期"];
    }else {
        [self sendNotificationMessage];
    }
}

- (void)addNotificationsWithDictArray:(NSArray *)array
{
    if (array.count > 0) {
        for (NSDictionary *dic in array) {
            NSInteger times = 0;
            
            //提醒时间的时间戳
            NSString *str = [NSString stringWithFormat:@"%@",[dic stringValueForKey:@"visit_remember"]];
            NSInteger rememberTimesp = [[[str nsDate:@"YYYY-MM-dd HH:mm"] strTimestamp13] integerValue];
            //当前时间戳
            NSInteger NowTimesp = [[NSDate currentStrTimestamp] integerValue];
            if (NowTimesp < rememberTimesp) {
                times = rememberTimesp - NowTimesp;
            }else{
                times = -1;
            }
            [self addNotification:dic[@"visit_id"] userData:@{kcontent: dic[@"visit_name"],ktimes : @(times)}];
            
        }
    }else{
        [self cancelAllLocalNotifications];
    }
}

//当前时间的时间戳
- (NSInteger )nowDateTimesp {
    return [[NSString stringWithFormat:@"%ld",(long)[[NSDate date] timeIntervalSince1970]] floatValue] * 1000;
}

#pragma MARK--- 本地推送
- (void)registerLocalNotification
{
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
        [self registeriOS10LocalNotification];
    } else {
        [self registeriOS8LocalNotification];
    }
}

- (void)registeriOS10LocalNotification
{
    //iOS10特有
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    // 必须写代理，不然无法监听通知的接收与点击
    center.delegate = self;
    
    /**
     UNNotificationActionOptionAuthenticationRequired: 锁屏时需要解锁才能触发事件，触发后不会直接进入应用
     UNNotificationActionOptionDestructive：字体会显示为红色，且锁屏时触发该事件不需要解锁，触发后不会直接进入应用
     UNNotificationActionOptionForeground：锁屏时需要解锁才能触发事件，触发后会直接进入应用界面
     */
    
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            //用户点击允许
            NSLog(@"注册成功");
            [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                NSLog(@"%@", settings);
            }];
        } else {
            //用户点击不允许
            NSLog(@"注册失败");
        }
    }];
}

- (void)registeriOS8LocalNotification
{
//    //创建动作(按钮)的类别集合
    UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
//    //这组动作的唯一标示
    category.identifier = self.notifyId;
//    //最多支持两个，如果添加更多的话，后面的将被忽略
//    [category setActions:@[] forContext:(UIUserNotificationActionContextMinimal)];
//    //创建UIUserNotificationSettings，并设置消息的显示类类型
    UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:[NSSet setWithObject:category]];
    [[UIApplication sharedApplication] registerUserNotificationSettings:uns];
}

#pragma MARK--发送通知方法
- (void)sendNotificationMessage {
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
        [self sendiOS10LocalNotification];
    } else {
        [self sendiOS8LocalNotification];
    }
}

- (void)sendiOS10LocalNotification
{
    
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    
    NSDictionary *dict =[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0],self.notifyId,nil];
    NSDate *now = [NSDate date];
    notification.fireDate=[now dateByAddingTimeInterval:[self.dict[ktimes] integerValue]/1000];
    notification.alertTitle = @"拜访内容";
    notification.alertBody= self.dict[kcontent];
    [notification setUserInfo:dict];
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    
//    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
//    content.body = self.dict[kcontent];
//    content.badge = @(1);
//    content.title = @"拜访内容";
//    content.categoryIdentifier = self.notifyId;
//    content.userInfo = @{self.notifyId: @"iOS10推送"};
//    
//    //推送类型
//    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:[self.dict[ktimes] integerValue]/1000 repeats:NO];
//    
//    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:self.notifyId content:content trigger:trigger];
//    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
//        NSLog(@"iOS 10 发送推送， error：%@", error);
//    }];
}

- (void)sendiOS8LocalNotification
{
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    //触发通知时间
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:[self.dict[ktimes] integerValue]/1000];
    //重复间隔
    //    localNotification.repeatInterval = kCFCalendarUnitMinute;
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    
    //通知内容
    localNotification.alertBody = self.dict[kcontent];
    localNotification.applicationIconBadgeNumber = 1;
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    
    //通知参数
    localNotification.userInfo = @{self.notifyId: @"iOS8推送"};
    
    localNotification.category = self.notifyId;
    
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}

#pragma mark - iOS10 接收推送的两个方法
/**
 本地和远程推送合为一个，通过 response.notification.request.trigger 来区分
 1.UNPushNotificationTrigger （远程通知） 远程推送的通知类型
 
 2.UNTimeIntervalNotificationTrigger （本地通知） 一定时间之后，重复或者不重复推送通知。我们可以设置timeInterval（时间间隔）和repeats（是否重复）。
 
 3.UNCalendarNotificationTrigger（本地通知） 一定日期之后，重复或者不重复推送通知 例如，你每天8点推送一个通知，只要dateComponents为8，如果你想每天8点都推送这个通知，只要repeats为YES就可以了。
 
 4.UNLocationNotificationTrigger （本地通知）地理位置的一种通知，
 当用户进入或离开一个地理区域来通知。在CLRegion标识符必须是唯一的。因为如果相同的标识符来标识不同区域的UNNotificationRequests，会导致不确定的行为。
 */
//接收到通知的事件
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    //这个和下面的userNotificationCenter:didReceiveNotificationResponse withCompletionHandler: 处理方法一样
    NSDictionary *userInfo = notification.request.content.userInfo;
    //收到推送的请求
    UNNotificationRequest *request = notification.request;
    //收到推送的内容
    UNNotificationContent *content = request.content;
    NSNumber *badge = content.badge;
    NSString *body = content.body;
    NSString *title = content.title;
    NSString *subTitle = content.subtitle;
    UNNotificationSound *sound = content.sound;
    
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        NSLog(@"iOS10 前台收到远程通知:%@", userInfo);
    } else {
        // 判断为本地通知
        NSLog(@"iOS10 应用在前台收到本地通知:{\\\\nbody:%@，\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge：%@，\\\\nsound：%@，\\\\nuserInfo：%@\\\\n}", body, title, subTitle, badge, sound, userInfo);
    }
    completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert); // 需要执行这个方法，选择是否提醒用户，有Badge、Sound、Alert三种类型可以设置
}

//通知的点击事件
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    //收到推送的请求
    UNNotificationRequest *request = response.notification.request;
    //收到推送的内容
    UNNotificationContent *content = request.content;
    NSNumber *badge = content.badge;
    NSString *body = content.body;
    NSString *title = content.title;
    NSString *subTitle = content.subtitle;
    UNNotificationSound *sound = content.sound;
    
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        NSLog(@"iOS10 前台收到远程通知:%@", userInfo);
    } else {
        // 判断为本地通知
        NSLog(@"iOS10 应用在后台点击推送消息收到本地通知:{\\\\nbody:%@，\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge：%@，\\\\nsound：%@，\\\\nuserInfo：%@\\\\n}", body, title, subTitle, badge, sound, userInfo);
    }
    NSString *actionIdentifile = response.actionIdentifier;
    
    completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法，选择是否提醒用户，有Badge、Sound、Alert三种类型可以设置
}

#pragma mark - iOS9 及之前方法
// (iOS9及之前)本地通知回调函数，当应用程序在前台时调用
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    NSLog(@"%@", notification.userInfo);
    NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badge -= notification.applicationIconBadgeNumber;
    badge = badge >= 0 ? badge : 0;
    [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
}

//在非本App界面时收到本地消息，下拉消息会有快捷回复的按钮，点击按钮后调用的方法，根据identifier来判断点击的哪个按钮，notification为消息内容
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler
{
    completionHandler();
}

- (void)cancelAllLocalNotifications;
{
    //直接取消全部本地通知
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
}

- (void)cancelLocalNotificationsWithID:(NSString *)ID{
    for (UILocalNotification *obj in [UIApplication sharedApplication].scheduledLocalNotifications) {
        if ([obj.userInfo.allKeys containsObject:ID]) {
            [[UIApplication sharedApplication] cancelLocalNotification:obj];
        }
    }
}

@end
